/*
ZhouSolver.h
Based on code posted to <http://forum.enjoysudoku.com/3-77us-solver-2-8g-cpu-testcase-17sodoku-t30470.html>
by user zhouyundong_2012.
The copyright is not specified.

this is a remorphing of the code to work in recursive mode
funtions have been added to work in generation mode
*/

/* the BIT_SET_30 pattern is defined in a band for a digit
   it is a map of candidates plus 3 bits for unsolved rows
   bits 0-8 9-17 18-26 for the rows 27-29 for unsolved rows
*/
struct BF3;
class GAME{
	struct GLOBAL { // global variables for the game table
		long long ncalls;
		unsigned long nctl;
		int nsol,lim;//,a,b,c,na,nb,nc; 
		word * ptcor;
		GAME * mytable;
		char * zsol,*puzfinal,*pat;
		// specific to the attempt to optimize the X+Y+27 process
		int numbers[9],nclues,tclues[15];
		GLOBAL();
	};
public:
	static GLOBAL glb;
	word index;
    int // BlockMaskSum[3],
		 F[27], //30-bit Full Mask
		 CompF[27];
	//	 BlockMask[27];
	void SetPat(char * pat,char * zsol,char * puzfinal){
		glb.pat=pat; glb.zsol=zsol; glb.puzfinal=puzfinal;
	};
	void InitSudoku(const char * ze,int indexe=0);
	int Update();
	int UpdateR4_9();// specific to X+Y+27 process 
	int DoUpdate();
	void Build(BF3 & rbf);
	int FullUpdate(BF3 & rbf);
	int DoUpdateR4_9();
	void Guess();
	void GuessR4_9();
	void Guess(int ibf,int irow); 
	void GuessR4_9(int ibf,int irow); 
	int IsValid(int digit,int cell);
	void Seta(int digit,int cell);
	inline void ComputeNext (){if(Update())Guess();}
	void SetKnown(char * zs);
	unsigned int SetGiven27();
	word GetFreeDigits(int cell);
	void SetFinal_Same_Pat();
	void GenScan17(word * tc,int ntc,int minfree=0);
	void GenGangsterEquivalences(word * tc,int ntc);
	void GenValid(word * tc,int ntc,int minfree=0);
	int IsPatFinalOk();
	int IsPatFinalOkR4_9();
	int CheckValidityQuick(char *puzzle,int igame);
	int isRedundant27(int cell, char * puzzle);
	int is27Valid(char * puzzle);
};

